<template>
  <view class="da-tree" :style="{ '--theme-color': themeColor }">
    <scroll-view class="da-tree-scroll" :scroll-y="true" :scroll-x="false">
      <view
        class="da-tree-item"
        :class="{ 'is-show': item.show }"
        :style="{ paddingLeft: item.level * indent + 'rpx' }"
        v-for="item in datalist"
        :key="item.key"
      >
        <view
          v-if="item.showArrow && !filterValue"
          class="da-tree-item__icon"
          @click="handleExpandedChange(item)"
        >
          <uni-icons
            v-if="loadLoading && item.loading"
            type="spinner-cycle"
            size="20"
            :class="['da-tree-item__icon--arr', 'is-loading']"
          />
          <uni-icons
            v-else
            :type="item.expand ? 'bottom' : 'right'"
            size="20"
            :class="['da-tree-item__icon--arr']"
          />
        </view>
        <view v-else class="da-tree-item__icon"></view>
        <view
          class="da-tree-item__checkbox"
          :class="[
            `da-tree-item__checkbox--${checkboxPlacement}`,
            { 'is--disabled': item.disabled },
          ]"
          v-if="showCheckbox"
          @click="handleCheckChange(item)"
        >
          <uni-icons
            v-if="item.checkedStatus === 2"
            type="checkbox-filled"
            size="20"
            color="var(--theme-color, #007aff)"
            class="da-tree-item__checkbox--icon"
          />
          <uni-icons
            v-else-if="item.checkedStatus === 1"
            type="minus-filled"
            size="20"
            color="var(--theme-color, #007aff)"
            class="da-tree-item__checkbox--icon"
          />
          <uni-icons
            v-else
            type="circle"
            size="20"
            color="#bbb"
            class="da-tree-item__checkbox--icon"
          />
        </view>
        <view
          class="da-tree-item__checkbox"
          :class="[
            `da-tree-item__checkbox--${checkboxPlacement}`,
            { 'is--disabled': item.disabled },
          ]"
          v-if="!showCheckbox && showRadioIcon"
          @click="handleRadioChange(item)"
        >
          <uni-icons
            v-if="item.checkedStatus === isCheckedStatus"
            type="circle-filled"
            size="20"
            color="var(--theme-color, #007aff)"
            class="da-tree-item__checkbox--icon"
          />
          <uni-icons
            v-else-if="item.checkedStatus === halfCheckedStatus"
            type="minus-filled"
            size="20"
            color="var(--theme-color, #007aff)"
            class="da-tree-item__checkbox--icon"
          />
          <uni-icons
            v-else
            type="circle"
            size="20"
            color="#bbb"
            class="da-tree-item__checkbox--icon"
          />
        </view>
        <view
          class="da-tree-item__label"
          :class="'da-tree-item__label--' + item.checkedStatus"
          @click="handleLabelClick(item)"
        >
          {{ item.label }}
          <text class="da-tree-item__label--append" v-if="item.append">{{
            item.append
          }}</text>
        </view>
      </view>
    </scroll-view>
  </view>
</template>

<script>
import {
  unCheckedStatus,
  halfCheckedStatus,
  isCheckedStatus,
  deepClone,
  getAllNodeKeys,
  getAllNodes,
  logError,
  isArray,
  isString,
  isNumber,
  isFunction,
} from "./utils";
import basicProps from "./props";

export default {
  name: "lu-data-tree",
  props: basicProps,

  computed: {
    isCheckedStatus() {
      return isCheckedStatus;
    },
    unCheckedStatus() {
      return unCheckedStatus;
    },
    halfCheckedStatus() {
      return halfCheckedStatus;
    },
  },

  data() {
    return {
      /** 原始的树数据 */
      dataRef: [],
      /** 处理后的一维树项数据 */
      datalist: [],
      /** 处理后的以key为键值的树项数据 */
      datamap: {},
      /** 默认的展开数据 */
      expandedKeys: [],
      /** 默认的已选数据 */
      checkedKeys: null,
      /** 加载状态 */
      loadLoading: false,
      /** 字段映射 */
      fieldMap: {
        value: "value",
        label: "label",
        children: "children",
        disabled: "disabled",
        leaf: "leaf",
        sort: "sort",
      },
    };
  },

  methods: {
    /**
     * 初始化数据结构
     */
    initData() {
      this.fieldMap = {
        value: this.valueField || "value",
        label: this.labelField || "label",
        children: this.childrenField || "children",
        disabled: this.disabledField || "disabled",
        append: this.appendField || "append",
        leaf: this.leafField || "leaf",
        sort: this.sortField || "sort",
      };

      const data = deepClone(this.dataRef);
      this.datalist = [];
      this.datamap = {};

      this.handleTreeData(data);
      this.datalist = this.checkInitData(this.datalist);
    },

    /**
     * 创建节点
     */
    createNewItem(item, index, parent, level) {
      const key = item[this.fieldMap.value];
      const label = item[this.fieldMap.label];
      const sort = item[this.fieldMap.sort] || 0;
      const children = item[this.fieldMap.children] || null;
      const append = item[this.fieldMap.append] || null;
      let disabled = item[this.fieldMap.disabled] || false;

      disabled = parent?.disabled || disabled;
      let isLeaf = isFunction(this.isLeafFn)
        ? this.isLeafFn(item)
        : item[this.fieldMap.leaf] || false;
      const isEmptyChildren = children && children.length === 0;
      let showArrow = true;
      let expand = this.defaultExpandAll || false;
      const isLoadMode = this.loadMode && isFunction(this.loadApi);

      if (!children) {
        expand = false;
        if (isLoadMode) {
          showArrow = true;
        } else {
          isLeaf = true;
          showArrow = false;
        }
      }

      if (isEmptyChildren) {
        expand = false;
        if (isLoadMode) {
          showArrow = true;
        } else {
          isLeaf = true;
          showArrow = false;
        }
      }

      if (isLeaf) {
        showArrow = false;
        expand = false;
      } else {
        showArrow = true;
      }

      if (!this.showCheckbox) {
        if (this.onlyRadioLeaf) {
          if (!isLeaf) {
            disabled = true;
          } else {
            disabled = parent?.originItem?.disabled || false;
          }
        }
      }

      if (disabled) {
        if (isLeaf || !children || isEmptyChildren) {
          expand = false;
          showArrow = false;
        }
      }

      const parentKey = parent ? parent.key : null;
      const show = this.defaultExpandAll || level === 0;

      const newItem = {
        key,
        parentKey,
        label,
        append,
        isLeaf,
        showArrow,
        level,
        expand,
        show,
        sort,
        disabled,
        loaded: false,
        loading: false,
        indexs: [index],
        checkedStatus: this.unCheckedStatus,
        parents: [],
        parentKeys: [],
        childrenKeys: [],
        children: [],
        originItem: item,
      };

      if (parent) {
        newItem.parentKeys = [parent.key, ...parent.parentKeys];
        newItem.parents = [...parent.parents, parent.originItem];
        newItem.indexs = [...parent.indexs, index];
      }

      return newItem;
    },

    /**
     * 转换为节点数据
     */
    handleTreeData(data = [], parent = null, level = 0, insertIndex = -1) {
      return data.reduce((prev, cur, index) => {
        const key = cur[this.fieldMap.value];
        const children = cur[this.fieldMap.children] || null;
        const newItem = this.createNewItem(cur, index, parent, level);

        if (insertIndex > -1) {
          // 插入子项尾部
          const index = (parent.childrenKeys?.length || 0) + insertIndex + 1;
          if (!parent?.childrenKeys?.includes(key)) {
            this.datamap[key] = newItem;
            this.datalist.splice(index, 0, newItem);
            parent.children.push(newItem);
            if (newItem.parentKeys?.length) {
              newItem.parentKeys.forEach((k) => {
                this.datamap[k].childrenKeys = [
                  ...this.datamap[k].childrenKeys,
                  newItem.key,
                ];
              });
            }
          }
        } else {
          this.datamap[key] = newItem;
          this.datalist.push(newItem);
        }

        const hasChildren = children && children.length > 0;
        if (hasChildren) {
          const childrenData = this.handleTreeData(
            children,
            newItem,
            level + 1
          );
          newItem.children = childrenData;
          const childrenKeys = childrenData.reduce((p, k) => {
            const keys = k.childrenKeys;
            p.push(...keys, k.key);
            return p;
          }, []);
          newItem.childrenKeys = childrenKeys;
        }
        prev.push(newItem);
        return prev;
      }, []);
    },

    /**
     * 处理初始化内容
     */
    checkInitData(list) {
      let checkedKeyList = null;
      let expandedKeyList = [];

      if (this.showCheckbox) {
        checkedKeyList = Array.isArray(this.defaultCheckedKeys)
          ? this.defaultCheckedKeys
          : [];
        this.checkedKeys = [...checkedKeyList];
        expandedKeyList = this.expandChecked
          ? [...checkedKeyList, ...(this.expandedKeys || [])]
          : this.expandedKeys;
      } else {
        checkedKeyList = this.defaultCheckedKeys || null;
        this.checkedKeys = checkedKeyList;
        expandedKeyList =
          this.expandChecked && checkedKeyList
            ? [checkedKeyList, ...(this.expandedKeys || [])]
            : this.expandedKeys;
      }

      if (
        checkedKeyList &&
        (Array.isArray(checkedKeyList) ? checkedKeyList.length > 0 : true)
      ) {
        this.handleCheckState(list, checkedKeyList, true);
      } else {
        list.forEach((item) => {
          item.checkedStatus = item.checkedStatus || 0;
        });
      }

      expandedKeyList = [...new Set(expandedKeyList)];
      if (!this.defaultExpandAll) {
        this.handleExpandState(list, expandedKeyList, true);
      }

      list.sort((a, b) => {
        if (a.sort === 0 && b.sort === 0) {
          return 0;
        }

        if (a.parentKey === b.parentKey) {
          if (a.sort - b.sort > 0) {
            return 1;
          } else {
            return -1;
          }
        }

        return 0;
      });

      return list;
    },

    /**
     * 处理选中状态
     */
    handleCheckState(list, checkedKeyList, checked = true) {
      // 多选
      if (this.showCheckbox) {
        if (checkedKeyList?.length) {
          checkedKeyList.forEach((k) => {
            const item = this.datamap[k];
            if (item) {
              this.checkTheChecked(item, checked);
            }
          });
        }
        return;
      }

      // 单选
      for (let i = 0; i < list.length; i++) {
        const item = list[i];
        if (item.key === checkedKeyList) {
          this.checkTheRadio(item, checked);
          break;
        }
      }
    },

    /**
     * 处理展开状态
     */
    handleExpandState(list, expandedKeyList, expand = true) {
      // 收起
      if (expand === false) {
        for (let i = 0; i < list.length; i++) {
          const item = list[i];
          if (expandedKeyList?.includes(item.key)) {
            item.expand = false;
            if (item.childrenKeys?.length) {
              item.childrenKeys.forEach((ck) => {
                this.datamap[ck].expand = false;
                this.datamap[ck].show = false;
              });
            }
          }
        }
        return;
      }

      // 展开
      for (let i = 0; i < list.length; i++) {
        const item = list[i];
        if (expandedKeyList?.includes(item.key)) {
          item.expand = true;
          if (item.children?.length) {
            item.children.forEach((k) => {
              const kItem = this.datamap[k.key];
              kItem.show = true;
            });
          }

          if (item.parentKeys?.length) {
            item.parentKeys.forEach((k) => {
              const kItem = this.datamap[k];
              kItem.expand = true;
              if (kItem.children?.length) {
                kItem.children.forEach((k) => {
                  const skItem = this.datamap[k.key];
                  skItem.show = true;
                });
              }
            });
          }
        }
      }
    },

    /**
     * 获取父类的选中状态
     */
    getParentCheckedStatus(item) {
      if (!item) {
        return unCheckedStatus;
      }

      if (!this.checkedDisabled && item.disabled) {
        return item.checkedStatus || unCheckedStatus;
      }

      // 单选时，父类永远为半选
      if (!this.showCheckbox) {
        return halfCheckedStatus;
      }

      const { children } = item;
      // 子类全选中
      const childrenCheckedAll = children.every(
        (k) => k.checkedStatus === isCheckedStatus
      );
      if (childrenCheckedAll) {
        return isCheckedStatus;
      }

      // 子类全不选中
      const childrenUncheckedAll = children.every(
        (k) => k.checkedStatus === unCheckedStatus
      );
      if (childrenUncheckedAll) {
        return unCheckedStatus;
      }

      return halfCheckedStatus;
    },

    /**
     * 校验多选节点
     */
    checkTheChecked(item, checked = true) {
      const { childrenKeys, parentKeys, disabled = false } = item;
      if (!this.checkedDisabled && disabled) return;

      // 当前
      item.checkedStatus = checked ? isCheckedStatus : unCheckedStatus;

      if (!this.checkStrictly) {
        // 子类
        childrenKeys.forEach((k) => {
          const childrenItem = this.datamap[k];
          childrenItem.checkedStatus =
            !this.checkedDisabled && childrenItem.disabled
              ? childrenItem.checkedStatus
              : item.checkedStatus;
        });

        // 父类
        parentKeys.forEach((k) => {
          const parentItem = this.datamap[k];
          parentItem.checkedStatus = this.getParentCheckedStatus(parentItem);
        });
      }
    },

    /**
     * 校验单选节点
     */
    checkTheRadio(item, checked) {
      const { parentKeys, isLeaf, disabled = false } = item;
      if (!this.checkedDisabled && disabled) return;

      // 限制末节点选中，但当前非末节点
      if (this.onlyRadioLeaf && !isLeaf) {
        logError(`限制了末节点选中，当前[${item.label}]非末点`);
        return;
      }

      if (this.datalist?.length) {
        this.datalist.forEach((k) => {
          k.checkedStatus = unCheckedStatus;
        });
      }

      parentKeys.forEach((k) => {
        const parentItem = this.datamap[k];
        parentItem.checkedStatus = checked
          ? this.getParentCheckedStatus(parentItem)
          : unCheckedStatus;
      });

      // 当前
      item.checkedStatus = checked ? isCheckedStatus : unCheckedStatus;
    },

    /**
     * 点击选框
     */
    handleCheckChange(item) {
      const {
        childrenKeys,
        parentKeys,
        checkedStatus,
        isLeaf,
        disabled = false,
      } = item;
      if (!this.showCheckbox || disabled) return;

      // 当前
      item.checkedStatus =
        checkedStatus === isCheckedStatus ? unCheckedStatus : isCheckedStatus;

      if (!this.checkStrictly) {
        if (this.expandChecked) {
          item.show = true;
          item.expand = childrenKeys?.length > 0 || isLeaf;
        }

        childrenKeys.forEach((k) => {
          const childrenItem = this.datamap[k];
          childrenItem.checkedStatus = childrenItem.disabled
            ? childrenItem.checkedStatus
            : item.checkedStatus;

          if (this.expandChecked) {
            childrenItem.show = true;
            childrenItem.expand =
              childrenItem?.childrenKeys?.length > 0 || childrenItem.isLeaf;
          }
        });

        parentKeys.forEach((k) => {
          const parentItem = this.datamap[k];
          parentItem.checkedStatus = this.getParentCheckedStatus(parentItem);
        });
      }

      const hasCheckedKeys = [];
      this.datalist.forEach((k) => {
        if (k.checkedStatus === isCheckedStatus) {
          if ((this.packDisabledkey && k.disabled) || !k.disabled) {
            hasCheckedKeys.push(k.key);
          }
        }
      });

      this.checkedKeys = hasCheckedKeys;
      this.$emit("change", hasCheckedKeys, item);
    },

    /**
     * 点击单选
     */
    handleRadioChange(item) {
      const { parentKeys, checkedStatus, key, disabled = false, isLeaf } = item;
      // 已经选中的,直接返回
      if (checkedStatus === isCheckedStatus) return;
      // 多选的,直接返回
      if (this.showCheckbox) return;
      if (this.onlyRadioLeaf && !isLeaf) this.handleExpandedChange(item);

      if (disabled) return;

      // 重置所有选择
      if (this.datalist?.length) {
        this.datalist.forEach((k) => {
          k.checkedStatus = unCheckedStatus;
        });
      }

      parentKeys.forEach((k) => {
        const parentItem = this.datamap[k];
        parentItem.checkedStatus = this.getParentCheckedStatus(parentItem);
      });

      // 当前
      item.checkedStatus =
        checkedStatus === isCheckedStatus ? unCheckedStatus : isCheckedStatus;

      this.checkedKeys = key;
      this.$emit("change", key, item);
    },

    /**
     * 点击标签
     */
    handleLabelClick(item) {
      if (this.showCheckbox) {
        this.handleCheckChange(item);
      } else {
        this.handleRadioChange(item);
      }
    },

    /**
     * 点击展开收起
     */
    async handleExpandedChange(item) {
      if (this.filterValue) return;

      const { expand, loading = false, disabled } = item;
      if (this.loadLoading && loading) return;

      this.checkExpandedChange(item);

      // 异步
      item.expand = !expand;

      let currentItem = null;
      if (!disabled) {
        if (!this.showCheckbox && this.onlyRadioLeaf && this.loadMode) {
          logError(`单选时，当 onlyRadioLeaf 为 true 时不支持动态数据`);
        } else {
          currentItem = await this.loadExpandNode(item);
        }
      }

      this.$emit("expand", !expand, currentItem || item || null);
    },

    /**
     * 检查展开状态
     */
    checkExpandedChange(item) {
      const { expand, childrenKeys, children = null } = item;

      if (expand) {
        if (childrenKeys?.length) {
          childrenKeys.forEach((k) => {
            if (this.datamap[k]) {
              this.datamap[k].show = false;
              this.datamap[k].expand = false;
            }
          });
        }
      } else {
        if (children?.length) {
          const childrenKeys = children.map((k) => k.key);
          childrenKeys.forEach((k) => {
            if (this.datamap[k]) {
              this.datamap[k].show = true;
            }
          });
        }
      }
    },

    /**
     * 加载异步数据
     */
    async loadExpandNode(item) {
      const { expand, key, loaded, children } = item;
      if (children?.length && !this.alwaysFirstLoad) {
        return item;
      }

      if (expand && this.loadMode && !loaded) {
        if (isFunction(this.loadApi)) {
          this.expandedKeys.push(key);
          this.loadLoading = true;
          item.loading = true;

          const currentNode = deepClone(item);
          const apiRes = await this.loadApi(currentNode);

          // 新增子项
          let newChildren = [
            ...(item.originItem?.children || []),
            ...(apiRes || []),
          ];
          const newChildrenObj = {};
          newChildren = newChildren.reduce((total, next) => {
            newChildrenObj[next[this.fieldMap.value]]
              ? ""
              : (newChildrenObj[next[this.fieldMap.value]] =
                  true && total.push(next));
            return total;
          }, []);

          item.originItem.children = newChildren || null;
          if (apiRes?.length) {
            const insertIndex = this.datalist.findIndex(
              (k) => k.key === item.key
            );
            this.handleTreeData(apiRes, item, item.level + 1, insertIndex);
            this.datalist = this.checkInitData(this.datalist);
          } else {
            // 加载后无数据就移除展开图标
            item.expand = false;
            item.isLeaf = true;
            item.showArrow = false;
          }

          this.loadLoading = false;
          item.loading = false;
          item.loaded = true;
        }
      } else {
        const eki = this.expandedKeys.findIndex((k) => k === key);
        if (eki >= 0) {
          this.expandedKeys.splice(eki, 1);
        }
      }

      return item;
    },

    /**
     * 对外暴露的方法
     */
    // 获取选中的 key
    getCheckedKeys() {
      return getAllNodeKeys(
        this.datalist,
        "checkedStatus",
        isCheckedStatus,
        this.packDisabledkey
      );
    },

    // 设置选中的 key
    setCheckedKeys(keys, checked = true) {
      // 多选
      if (this.showCheckbox) {
        if (!isArray(keys)) {
          logError(`setCheckedKeys 第一个参数非数组，传入的是[${keys}]`);
          return;
        }

        const list = this.datalist;

        // 取消选择
        if (checked === false) {
          let newCheckedKeys = [];
          for (let i = 0; i < this.checkedKeys.length; i++) {
            const ck = this.checkedKeys[i];
            if (!keys.includes(ck)) {
              newCheckedKeys.push(ck);
            }
          }
          newCheckedKeys = [...new Set(newCheckedKeys)];
          this.checkedKeys = newCheckedKeys;
          this.handleCheckState(list, keys, false);
          return;
        }

        // 选择
        const newCheckedKeys = [...this.checkedKeys, ...keys];
        this.checkedKeys = [...new Set(newCheckedKeys)];
        this.handleCheckState(list, this.checkedKeys, true);

        if (this.expandChecked && checked) {
          this.expandedKeys = [
            ...new Set([...(this.checkedKeys || []), ...(keys || [])]),
          ];
          this.handleExpandState(list, keys, true);
        }
        return;
      }

      // 单选
      // 如果为数组则拿第一个
      if (isArray(keys)) {
        keys = keys[0];
      }

      if (!isString(keys) && !isNumber(keys)) {
        logError("setCheckedKeys 第一个参数字符串或数字，传入的是==>", keys);
        return;
      }

      const list = this.datalist;
      this.checkedKeys = checked ? keys : null;

      if (this.expandChecked && checked) {
        this.handleExpandState(list, [keys], true);
      }

      this.handleCheckState(list, keys, !!checked);
    },

    // 获取半选的 key
    getHalfCheckedKeys() {
      return getAllNodeKeys(
        this.datalist,
        "checkedStatus",
        halfCheckedStatus,
        this.packDisabledkey
      );
    },

    // 获取未选的 key
    getUncheckedKeys() {
      return getAllNodeKeys(
        this.datalist,
        "checkedStatus",
        unCheckedStatus,
        this.packDisabledkey
      );
    },

    // 获取已展开的 key
    getExpandedKeys() {
      return getAllNodeKeys(this.datalist, "expand", true);
    },

    // 获取未展开的 key
    getUnexpandedKeys() {
      return getAllNodeKeys(this.datalist, "expand", false);
    },

    // 设置展开/收起的 key
    setExpandedKeys(keys, expand = true) {
      if (!Array.isArray(keys) && keys !== "all") {
        logError("setExpandedKeys 第一个参数非数组，传入的是===>", keys);
        return;
      }

      const list = this.datalist;

      // 展开/收起全部
      if (keys === "all") {
        list.forEach((k) => {
          k.expand = expand;
          if (k.level > 0) {
            k.show = expand;
          }
        });
        return;
      }

      // 收起
      if (expand === false) {
        const newExpandedKeys = [];
        for (let i = 0; i < this.expandedKeys.length; i++) {
          const ek = this.expandedKeys[i];
          if (!keys.includes(ek)) {
            newExpandedKeys.push(ek);
          }
        }
        this.expandedKeys = [...new Set(newExpandedKeys)];
        this.handleExpandState(list, keys, false);
        return;
      }

      // 展开
      const newExpandedKeys = [];
      for (let i = 0; i < list.length; i++) {
        if (keys.includes(list[i].key)) {
          newExpandedKeys.push(list[i].key);
        }
      }
      this.expandedKeys = [...new Set(newExpandedKeys)];
      this.handleExpandState(list, newExpandedKeys, true);
    },

    // 获取选中的节点
    getCheckedNodes() {
      return getAllNodes(
        this.datalist,
        "checkedStatus",
        isCheckedStatus,
        this.packDisabledkey
      );
    },

    // 获取半选的节点
    getHalfCheckedNodes() {
      return getAllNodes(
        this.datalist,
        "checkedStatus",
        halfCheckedStatus,
        this.packDisabledkey
      );
    },

    // 获取未选的节点
    getUncheckedNodes() {
      return getAllNodes(
        this.datalist,
        "checkedStatus",
        unCheckedStatus,
        this.packDisabledkey
      );
    },

    // 获取已展开的节点
    getExpandedNodes() {
      return getAllNodes(this.datalist, "expand", true);
    },

    // 获取未展开的节点
    getUnexpandedNodes() {
      return getAllNodes(this.datalist, "expand", false);
    },
  },

  watch: {
    defaultExpandedKeys: {
      handler(v) {
        if (v?.length) {
          this.expandedKeys = v;
        } else {
          this.expandedKeys = [];
        }
      },
      immediate: true,
    },
    defaultCheckedKeys: {
      handler(v) {
        if (this.showCheckbox) {
          this.checkedKeys = v?.length ? v : [];
        } else {
          this.checkedKeys = v || v === 0 ? v : null;
        }
      },
      immediate: true,
    },
    data: {
      handler(v) {
        this.dataRef = deepClone(v);
        setTimeout(() => {
          this.initData();
        }, 36);
      },
      immediate: true,
      deep: true,
    },
    filterValue() {
      this.filterData();
    },
  },
};
</script>

<style lang="scss" scoped>
.da-tree {
  width: 100%;
  height: 100%;

  &-scroll {
    width: 100%;
    height: 100%;
  }

  &-item {
    display: flex;
    align-items: center;
    height: 0;
    padding: 0;
    overflow: hidden;
    font-size: 28rpx;
    line-height: 1;
    visibility: hidden;
    opacity: 0;
    transition: opacity 0.2s linear;

    &.is-show {
      height: auto;
      padding: 12rpx 24rpx;
      visibility: visible;
      opacity: 1;
    }

    &__icon {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 40rpx;
      height: 40rpx;
      overflow: hidden;

      &--arr {
        position: relative;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 32rpx;
        height: 32rpx;

        &::after {
          position: relative;
          z-index: 1;
          overflow: hidden;
          /* stylelint-disable-next-line font-family-no-missing-generic-family-keyword */
          font-family: "da-tree-iconfont" !important;
          font-size: 32rpx;
          font-style: normal;
          color: #999;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }

        &.is-expand {
          &::after {
            content: "\e604";
          }
        }

        &.is-right {
          transform: rotate(-90deg);
        }

        &.is-loading {
          animation: IconLoading 1s linear 0s infinite;

          &::after {
            content: "\e7f1";
          }
        }
      }
    }

    &__checkbox {
      width: 40rpx;
      height: 40rpx;
      overflow: hidden;

      &--left {
        order: 0;
      }

      &--right {
        order: 1;
      }

      &--icon {
        position: relative;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 40rpx !important;
        height: 40rpx !important;
        display: flex !important;
        align-items: center !important;
        justify-content: center !important;
      }

      &.is--disabled {
        cursor: not-allowed;
        opacity: 0.35;
      }
    }

    &__label {
      flex: 1;
      margin-left: 4rpx;
      color: #555;

      &--2 {
        color: var(--theme-color, #007aff);
      }

      &--append {
        font-size: 60%;
        opacity: 0.6;
      }
    }
  }
}

@keyframes IconLoading {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}
</style>
